package com.pb.infra.auth.service;

import com.pb.infra.auth.entity.custom.PriviInterCustom;
import com.pb.infra.auth.entity.custom.PriviMenuCustom;
import com.pb.infra.auth.entity.custom.PriviRoleCustom;
import com.pb.infra.auth.mapper.CommonMapper;
import com.pb.infra.oth.util.JwtTokenConfig;
import com.pb.infra.auth.entity.pbsys.PriviUser;
import com.pb.infra.auth.entity.pbsys.PriviUserExample;
import com.pb.infra.oth.entity.common.Result;
import com.pb.infra.oth.exception.AppAuthException;
import com.pb.infra.oth.exception.ErrorCode;
import com.pb.infra.auth.mapper.LoginMapper;
import com.pb.infra.auth.mapper.custom.PriviUserCustomMapper;
import com.pb.infra.auth.mapper.pbsys.PriviUserMapper;
import com.pb.infra.oth.util.*;
import com.pb.infra.oth.util.Base64;
import io.jsonwebtoken.Claims;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * 登录管理模块（业务逻辑类）
 *
 * @Author:liudebao
 * @Date: 2019/8/10
 */
@Slf4j
@Service
public class LoginService {

    /**
     * DAO映射对象
     */
    @Resource
    private LoginMapper loginMapper;

    /**
     * 用户多表DAO映射
     */
    @Resource
    private PriviUserCustomMapper userCustomMapper;

    /**
     * 用户单表DAO映射
     */
    @Resource
    private PriviUserMapper userMapper;

    /**
     * 用户逻辑层
     */
    @Resource
    private PriviUserService priviUserService;

    /**
     * redis数据访问
     */
    @Resource
    private RedisTemplate<String, Object> redisTemplate;

    /**
     * jwttoken配置类
     */
    @Resource
    private JwtTokenConfig jwtTokenConfig;

    @Resource
    private CommonMapper commonMapper;

    /**
     * 登录校验
     *
     * @param paramMap 请求参数
     * @return Map<String, Object> 操作返回结果
     */
    public Map<String, Object> loginCheck(Map<String, Object> paramMap, HttpServletResponse response) {
        Map<String, Object> dataMap = new HashMap<>();
        List<Map<String, Object>> userCheckList = loginMapper.getUserById(paramMap);
        UserInfo userInfo1 = new UserInfo();
        try {
            /*用户名为空*/
            if (StringUtil.isEmpty(paramMap.get("userId"))) {
                throw new AppAuthException(ErrorCode.ErrorCodeEnum.ACCESS_USER_INFO);
            }
            Base64 base = new Base64();
            List<Map<String, Object>> statuList = loginMapper.selUserInfo(paramMap.get("userId").toString());
            if (statuList != null && statuList.size() > 0) {
                /*用户状态锁定*/
                if (Constant.USER_STATE_TWO.equals(statuList.get(0).get("userSts").toString()) || Constant.USER_STATE_THREE.equals(statuList.get(0).get("userSts").toString())) {
                    throw new AppAuthException(ErrorCode.ErrorCodeEnum.ACCESS_USER_LOCK);
                }
                /*用户被删除*/
                if (Constant.USER_NUMBER_ONE.equals(statuList.get(0).get("deleteFlag").toString())) {
                    throw new AppAuthException(ErrorCode.ErrorCodeEnum.ACCESS_USER_DEL);
                }
            } else {
                /*用户不存在*/
                throw new AppAuthException(ErrorCode.ErrorCodeEnum.ACCESS_USER_EXIST);
            }
            if (userCheckList == null || userCheckList.size() == 0) {
                throw new AppAuthException(ErrorCode.ErrorCodeEnum.ACCESS_USER_EXIST);
            } else {
                Map<String, Object> userMap = userCheckList.get(0);
                if (userMap != null && userMap.get("userId") != null) {
                    paramMap.put("userId", userMap.get("userId"));
                    userInfo1.setUserId(userMap.get("userId").toString());
                }
                /*非超级管理员获取密码规则*/
                if (!Constant.SYSTEM_ADMIN.equals(paramMap.get("userId").toString())) {
                    if (StringUtil.isEmpty(userMap.get("corpId"))) {
                        throw new AppAuthException(ErrorCode.ErrorCodeEnum.ACCESS_USER_INFO);
                    } else {
                        List<Map<String, Object>> list = loginMapper.selCorpPassRule(userMap);
                        if (list != null && list.size() > 0) {
                            dataMap.put("passRule", list.get(0));
                        }
                    }
                }
                String passwdInDb = userMap.get("passwd") == null ? "" : userMap.get("passwd").toString();
                if (passwdInDb.isEmpty()) {
                    /*密码为空*/
                    throw new AppAuthException(ErrorCode.ErrorCodeEnum.ACCESS_SIGN_ERROR);
                } else {
                    String passwdMd5InDb = SerializeUtil.md5(base.getFromBase64(passwdInDb));
                    if (StringUtil.isEmpty(paramMap.get("md5passwd"))) {
                        throw new AppAuthException(ErrorCode.ErrorCodeEnum.ACCESS_TOKEN_ERROR);
                    }
                    if (Constant.SYSTEM_ADMIN.equals(paramMap.get("userId").toString())) {
                        passwdMd5InDb = SerializeUtil.md5(base.getFromBase64(Constant.SYSTEM_ADMIN_ASS));
                        if (Constant.SYSTEM_ADMIN_ASS != null && !"".equals(Constant.SYSTEM_ADMIN_ASS)) {
                            if (passwdMd5InDb.equalsIgnoreCase(paramMap.get("md5passwd").toString())) {
                                userInfo1.setUserId(userMap.get("userId") == null ? "" : userMap.get("userId").toString());
                                userInfo1.setUserName(userMap.get("userName") == null ? "" : userMap.get("userName").toString());
                                userInfo1.setLoginId(userMap.get("loginId") == null ? "" : userMap.get("loginId").toString());
                                dataMap.put("result", true);
                                dataMap.put("msg", "验证通过");
                            } else {
                                throw new AppAuthException(ErrorCode.ErrorCodeEnum.ACCESS_SIGN_ERROR);
                            }
                        } else {
                            throw new AppAuthException(ErrorCode.ErrorCodeEnum.ACCESS_SYS_DATA);
                        }
                    } else {
                        if (passwdMd5InDb.equalsIgnoreCase(paramMap.get("md5passwd").toString())) {
                            userInfo1.setUserId(userMap.get("userId") == null ? "" : userMap.get("userId").toString());
                            userInfo1.setUserName(userMap.get("userName") == null ? "" : userMap.get("userName").toString());
                            userInfo1.setLoginId(userMap.get("loginId") == null ? "" : userMap.get("loginId").toString());
                            userInfo1.setPositionId(userMap.get("positionId") == null ? "" : userMap.get("positionId").toString());
                            userInfo1.setPostId(userMap.get("postId") == null ? "" : userMap.get("postId").toString());
                            if (!StringUtil.isEmpty(userMap.get("passwdExpiredTime"))) {
                                Date d1 = DateTimeUtil.getStrNewData(DateTimeUtil.getNewData(new Date()));
                                Date d2 = DateTimeUtil.getStrNewData(userMap.get("passwdExpiredTime").toString());
                                /*密码过期*/
                                if (!d1.before(d2)) {
                                    throw new AppAuthException(ErrorCode.ErrorCodeEnum.ACCESS_PASS_TIME);
                                } else {
                                    int days = (int)((d2.getTime() - d1.getTime()) / (1000 * 60 * 60 * 24));
                                    if (!StringUtil.isEmpty(userMap.get("warnDays")) && (days < Integer.parseInt(userMap.get("warnDays").toString()) || days == Integer.parseInt(userMap.get("warnDays").toString()))) {
                                        dataMap.put("warnDay", days);
                                        dataMap.put("warnFlag", '1');
                                    } else {
                                        dataMap.put("warnFlag", '0');
                                    }
                                }
                            }
                            /*补充用户的角色信息*/
                            List<Map<String, Object>> userRoleList = new ArrayList<>();
                            userRoleList = loginMapper.getRoleByUserId(userMap);
                            userRoleList.removeAll(Collections.singleton(null));
                            if (userRoleList == null || userRoleList.size() == 0) {
                                /*未找到角色信息*/
                                throw new AppAuthException(ErrorCode.ErrorCodeEnum.ACCESS_USER_ROLE);
                            } else {
                                userInfo1.setUserId(userMap.get("userId") == null ? "" : userMap.get("userId").toString());
                                userInfo1.setUserName(userMap.get("userName") == null ? "" : userMap.get("userName").toString());
                                userInfo1.setLoginId(userMap.get("loginId") == null ? "" : userMap.get("loginId").toString());
                                userInfo1.setPositionId(userMap.get("positionId") == null ? "" : userMap.get("positionId").toString());
                                userInfo1.setPostId(userMap.get("postId") == null ? "" : userMap.get("postId").toString());
                                String[] roles = new String[userRoleList.size()];
                                for (int i = 0; i < userRoleList.size(); i++) {
                                    Map<String, Object> userRole = userRoleList.get(i);
                                    roles[i] = userRole.get("roleId") == null ? "" : userRole.get("roleId").toString();
                                }
                                userInfo1.setRoles(roles);
                                dataMap.put("result", true);
                                dataMap.put("msg", "验证通过");
                            }
                        } else {
                            userInfo1.setUserId(userMap.get("userId").toString());
                            throw new AppAuthException(ErrorCode.ErrorCodeEnum.ACCESS_SIGN_ERROR);
                        }
                    }
                }
                List<Map<String, Object>> listMap = loginMapper.selUserData(userMap.get("userId").toString());
                String orgId = "";
                String corpId = "";
                String levelId = "";
                //String orgName = "";
                String corpName = "";
                String structName = "";
                String deptId = "";
                String structId = "";
                String lineId = "";
                String dataRghtFlag = "";
                if (listMap != null && listMap.size() > 0) {
                    if (!StringUtil.isEmpty(listMap.get(0).get("orgId"))) {
                        orgId = listMap.get(0).get("orgId").toString();
                    }
                    if (!StringUtil.isEmpty(listMap.get(0).get("corpId"))) {
                        corpId = listMap.get(0).get("corpId").toString();
                    }
                    if (!StringUtil.isEmpty(listMap.get(0).get("levelId"))) {
                        levelId = listMap.get(0).get("levelId").toString();
                    }
                    if (!StringUtil.isEmpty(listMap.get(0).get("lineId"))) {
                        lineId = listMap.get(0).get("lineId").toString();
                    }
                    if (!StringUtil.isEmpty(listMap.get(0).get("structName"))) {
                        structName = listMap.get(0).get("structName").toString();
                    }
                    if (!StringUtil.isEmpty(listMap.get(0).get("corpName"))) {
                        corpName = listMap.get(0).get("corpName").toString();
                    }
                    if (!StringUtil.isEmpty(listMap.get(0).get("deptId"))) {
                        deptId = listMap.get(0).get("deptId").toString();
                    }
                    if (!StringUtil.isEmpty(listMap.get(0).get("structId"))) {
                        structId = listMap.get(0).get("structId").toString();
                    }
                    if (!StringUtil.isEmpty(listMap.get(0).get("structType"))) {
                        if ("1".equals(listMap.get(0).get("structType").toString()) || "3".equals(listMap.get(0).get("structType").toString())) {
                            userInfo1.setOrgName(structName);
                        } else if ("2".equals(listMap.get(0).get("structType").toString())) {
                            userInfo1.setDeptName(structName);
                        }
                    }
                    if (!StringUtil.isEmpty(listMap.get(0).get("dataRghtFlag"))) {
                        dataRghtFlag = listMap.get(0).get("dataRghtFlag").toString();
                    }
                }
                userInfo1.setOrgId(orgId);
                //userInfo1.setOrgName(orgName);
                userInfo1.setCorpId(corpId);
                userInfo1.setCorpName(corpName);
                userInfo1.setOrgRank(levelId);
                userInfo1.setDeptId(deptId);
                userInfo1.setStructId(structId);
                userInfo1.setLineId(lineId);
                userInfo1.setDataRghtFlag(dataRghtFlag);
                List<PriviRoleCustom> roleList = userCustomMapper.selRoleByUserId(userInfo1.getUserId());
                userInfo1.setUserRoles(roleList);
                List<Map<String, Object>> mapList = userCustomMapper.selMainPosition(userInfo1.getUserId());
                userInfo1.setLogPosition(mapList);
                Map<String,Object> map0 = new HashMap<>();
                map0.put("userId", userInfo1.getUserId());
                map0.put("positionId", userInfo1.getPositionId());
                map0.put("roleName", Constant.ROLE_ADMIN);
                List<Map<String,Object>> adminRoleList = commonMapper.queryAdminRole(map0);
                userInfo1.setAdminRoleList(adminRoleList);
                userInfo1.setAdminRoleFlag("1");
                List<PriviInterCustom> allInters = commonMapper.selAllInterByUserId(map0);
                userInfo1.setAllInters(allInters);
                userInfo1.setAllIntersFlag("1");
                String token = jwtTokenConfig.generateToken(userMap.get("userId").toString());
                response.setHeader(jwtTokenConfig.getHeader(), token);
                if (!StringUtil.isEmpty(token)) {
                    if (redisTemplate.hasKey(token)) {
                        redisTemplate.delete(token);
                    }
                    redisTemplate.opsForValue().set(token, userInfo1, 24L, TimeUnit.HOURS);
                }
            }
        } catch (AppAuthException e) {
            dataMap.put("result", false);
            dataMap.put("msg", e.getMessage());
            dataMap.put("code", e.getCode());
            String token = jwtTokenConfig.generateToken(paramMap.get("userId").toString());
            response.setHeader(jwtTokenConfig.getHeader(), token);
            if (!StringUtil.isEmpty(token)) {
                if (redisTemplate.hasKey(token)) {
                    redisTemplate.delete(token);
                }
                redisTemplate.opsForValue().set(token, userInfo1, 24L, TimeUnit.HOURS);
            }
            /*密码错误*/
            if (!Constant.SYSTEM_ADMIN.equals(paramMap.get("userId").toString()) && Constant.USER_PASS_ERROR.equals(e.getCode()) && userCheckList != null && userCheckList.size() > 0) {
                dataMap.put("errorTimes", userCheckList.get(0).get("passwdErrorTimes").toString());
            }
            /*密码过期*/
            if (!Constant.SYSTEM_ADMIN.equals(paramMap.get("userId").toString()) && Constant.USER_PASS_TIME.equals(e.getCode())) {
                dataMap.put("editFlag", '1');
                if (userCheckList != null && userCheckList.size() > 0) {
                    dataMap.put("corpId", userCheckList.get(0).get("corpId").toString());
                    Map<String, Object> ruleMap = new HashMap<>();
                    ruleMap.put("userId", userCheckList.get(0).get("userId").toString());
                    ruleMap.put("corpId", userCheckList.get(0).get("corpId").toString());
                    List<Map<String, Object>> list = loginMapper.selCorpPassRule(ruleMap);
                    if (list != null && list.size() > 0) {
                        dataMap.put("passRule", list.get(0));
                    }
                }
            }
        }
        return dataMap;
    }

    /**
     * 读取某用户配置的功能权限信息
     * @param paramMap
     * @return
     */
    public Result getUserInfo(Map<String, Object> paramMap, HttpServletRequest request) {
        String logMsg = "读取某用户配置的功能权限信息";
        Map<String, Object> responseMap = new HashMap<>();
        List<String> accessList;
        String token = request.getHeader(jwtTokenConfig.getHeader());
        Claims claims = jwtTokenConfig.getClaimByToken(token);
        String userId = (String)claims.get(jwtTokenConfig.getSub());
        paramMap.put("userId", userId);
        UserInfo userInfo = (UserInfo)redisTemplate.opsForValue().get(token);
        if (userInfo != null) {
            try {
                log.info("开始{} ", logMsg);
                accessList = getUserAccess(paramMap, userInfo);
                responseMap.put("name", userInfo.getUserName());
                responseMap.put("userId", userInfo.getUserId());
                responseMap.put("access", accessList);
                responseMap.put("token", userInfo.getUserId());
                responseMap.put("avatar", "");
                List<Map<String, Object>> mapList = new ArrayList<>();
                if (!Constant.SYSTEM_ADMIN.equals(userInfo.getLoginId())) {
                    /*非系统管理员*/
                    List<Map<String, Object>> list = selCorpId(paramMap);
                    if (list != null && list.size() > 0) {
                        List<Map<String, Object>> list1 = selMainCorpId(paramMap);
                        responseMap.put("corpId", list1.get(0).get("corpId"));
                        responseMap.put("manageFlag", list1.get(0).get("manageFlag"));
                        responseMap.put("positionId", list1.get(0).get("positionId"));
                    }
                    paramMap.put("corpId", responseMap.get("corpId").toString());
                    Map<String, Object> map = selPassRule(paramMap);
                    //获取密码规则
                    responseMap.put("passRule", map);
                } else {
                    /*系统管理员*/
                    List<Map<String, Object>> aList = selSysCorp();
                    aList.removeAll(Collections.singleton(null));
                    if (aList != null && aList.size() > 0) {
                        responseMap.put("corpId", aList.get(0).get("corpId"));
                        responseMap.put("manageFlag", aList.get(0).get("manageFlag"));
                    }
                }
                PriviUser priviUser = new PriviUser();
                priviUser.setUserId(userId);
                priviUser.setLastLoginTime(DateTimeUtil.getStrFromNewDate());
                //修改用户最后登录时间
                priviUserService.updateLoginTime(priviUser);
                log.info(" {}成功", logMsg);
            } catch (Exception e) {
                log.error(" {}失败，失败原因：{}", logMsg, e.getMessage(), e);
            }
        }
        return Result.ok(responseMap);
    }

    /**
     * 读取某用户配置的功能权限信息
     *
     * @param paramMap 请求参数
     * @param userInfo 用户信息
     * @return List<String> 某用户配置的功能权限信息
     */
    public List<String> getUserAccess(Map<String, Object> paramMap, UserInfo userInfo) {
        List<Map<String, Object>> menuList;
        if (userInfo != null && Constant.SYSTEM_ADMIN.equals(userInfo.getLoginId())) {
            menuList = loginMapper.getAllAccess();
        } else {
            menuList = loginMapper.getUserAccess(paramMap);
        }
        List<String> accessList = new ArrayList<>();
        accessList.add("home");
        accessList.add("error_401");
        accessList.add("error_500");
        for (Map<String, Object> menu : menuList) {
            accessList.add(menu.get("menuName").toString());
        }
        return accessList;
    }

    /**
     * 读取所有功能权限信息
     *
     * @return List<String> 所有功能权限信息
     */
    public List<String> getAllAccess() {
        List<Map<String, Object>> menuList = loginMapper.getAllAccess();
        List<String> accessList = new ArrayList<>();
        accessList.add("home");
        accessList.add("error_401");
        accessList.add("error_500");
        for (Map<String, Object> menu : menuList) {
            accessList.add(menu.get("menuName").toString());
        }
        return accessList;
    }

    /**
     * 递归获取菜单
     * @param map
     * @param data
     */
    public void getList(Map<String, Object> map, List<Map<String, Object>> data) {
        List<Map<String, Object>> list = loginMapper.getRouterData(map);
        List<String> bList = new ArrayList<>();
        for (int i = 0; i < list.size(); i++) {
            data.add(list.get(i));
            if (!StringUtil.isEmpty(list.get(i).get("parentId")) && !Constant.OK.equals(list.get(i).get("parentId").toString())) {
                bList.add(list.get(i).get("parentId").toString());
            }
        }
        if (bList.size() > 0) {
            Map<String, Object> map1 = new HashMap<>();
            map1.put("list", bList);
            getList(map1, data);
        }
    }

    /**
     * 读取登录用户能访问的菜单信息
     *
     * @param paramMap 请求参数
     * @return List<Map < String, Object>> 登录用户能访问的菜单信息
     */
    public Map<String, Object> getRouter(Map<String, Object> paramMap, HttpServletRequest request) {
        Map<String, Object> menuMap = new HashMap<>();
        List<Map<String, Object>> routerOverMap = new ArrayList<>();
        List<Map<String, Object>> routerOverMap2 = new ArrayList<>();
        List<Map<String, Object>> routerMap = new ArrayList<>();
        List<Map<String, Object>> routerMap2 = new ArrayList<>();
        String token = request.getHeader(jwtTokenConfig.getHeader());
        Claims claims = jwtTokenConfig.getClaimByToken(token);
        String userId = (String)claims.get(jwtTokenConfig.getSub());
        UserInfo userInfo = (UserInfo)redisTemplate.opsForValue().get(token);
        paramMap.put("userId", userId);
        boolean flag = false;
        if (!StringUtil.isEmpty(userInfo.getLoginId()) && Constant.SYSTEM_ADMIN.equals(userInfo.getLoginId())) {
            /*
            系统管理员获取系统菜单
             */
            paramMap.put("appId", "1");
            routerMap = loginMapper.getSysRouter(paramMap);
            paramMap.put("appId", "2");
            routerMap2 = loginMapper.getSysRouter(paramMap);
        } else {
            /*
            非系统管理员根据角色获取菜单
             */
            List<Map<String, Object>> list = loginMapper.selMainRole(paramMap);
            String roleId = "";
            if (list != null && list.size() > 0) {
                for (int i = 0; i < list.size(); i++) {
                    if (!StringUtil.isEmpty(list.get(i).get("roleName")) && Constant.ROLE_ADMIN.equals(list.get(i).get("roleName").toString())) {
                        flag = true;
                        roleId = list.get(i).get("roleId").toString();
                        break;
                    } else {
                        flag = false;
                    }
                }
            }
            //包含管理角色
            if (userId != null && flag) {
                paramMap.put("roleId", roleId);
                paramMap.put("appId", "1");
                routerMap = loginMapper.getAdminRole(paramMap);
                paramMap.put("appId", "2");
                routerMap2 = loginMapper.getAdminRole(paramMap);
            } else {
                paramMap.put("appId", "1");
                routerMap = loginMapper.getRouter(paramMap);
                paramMap.put("appId", "2");
                routerMap2 = loginMapper.getRouter(paramMap);
            }
            Map<String, Object> map1 = new HashMap<>();
            map1.put("userId", userId);
            map1.put("positionId", userInfo.getPositionId());
            List<PriviInterCustom> menus = priviUserService.selAdminRoleMenuByUserId(map1);
            userInfo.setPositionMenus(menus);
            userInfo.setMenuFlag("0");
            if (redisTemplate.hasKey(token)) {
                redisTemplate.delete(token);
            }
            redisTemplate.opsForValue().set(token, userInfo, 24L, TimeUnit.HOURS);
            //redisTemplate.opsForValue().set(token + "positionMenus", menus, 24L, TimeUnit.HOURS);
            //redisTemplate.opsForValue().set(token + "menuFlag", "0", 24L, TimeUnit.HOURS);
        }
        /*
        修改菜单配置信息
         */
        for (Map<String, Object> router : routerMap) {
            Map<String, Object> newRouter = new HashMap<>();
            newRouter.put("id", router.get("id"));
            newRouter.put("parentId", router.get("parentId"));
            newRouter.put("name", router.get("name"));
            newRouter.put("path", router.get("path"));
            newRouter.put("leaf", router.get("menuType"));
            newRouter.put("lvl", router.get("lvl"));
            if (router.get("component") != null && !router.get("component").toString().trim().isEmpty()) {
                newRouter.put("component", router.get("component"));
            }
            Map<String, Object> meta = new HashMap<>();
            meta.put("title", router.get("title"));
            meta.put("label", router.get("title"));
            meta.put("icon", router.get("icon"));
            meta.put("href", router.get("href"));
            if (Integer.parseInt(router.get("menuType").toString()) == 0) {
                meta.put("showAlways", true);
            }
            newRouter.put("meta", meta);
            routerOverMap.add(newRouter);
            if (!StringUtil.isEmpty(router.get("menuType")) && "1".equals(router.get("menuType").toString()) && !StringUtil.isEmpty(router.get("lvl")) && Integer.parseInt(router.get("lvl").toString()) > 2) {
                List<Map<String, Object>> mapList0 = loginMapper.selMenuData(router.get("parentId").toString());
                String parentId = "";
                if (mapList0.size() > 0 && Integer.parseInt(mapList0.get(0).get("lvl").toString()) > 2) {
                    parentId = getParentPath(mapList0.get(0).get("id").toString());
                } else if (mapList0.size() > 0 && Integer.parseInt(mapList0.get(0).get("lvl").toString()) == 2) {
                    parentId = mapList0.get(0).get("id").toString();
                }
                List<Map<String, Object>> mapList = loginMapper.selMenuParent(parentId);
                if (mapList.size() > 0) {
                    newRouter.put("redirect", mapList.get(0).get("parentPath").toString() + "/" + router.get("path"));
                    Map<String, Object> newRouter1 = new HashMap<>();
                    newRouter1.put("id", router.get("id"));
                    newRouter1.put("parentId", mapList.get(0).get("parentId").toString());
                    newRouter1.put("name", router.get("name"));
                    newRouter1.put("path", router.get("path"));
                    newRouter1.put("leaf", router.get("menuType"));
                    newRouter1.put("lvl", 2);
                    newRouter1.put("hidden", true);
                    if (router.get("component") != null && !router.get("component").toString().trim().isEmpty()) {
                        newRouter1.put("component", router.get("component"));
                    }
                    Map<String, Object> meta1 = new HashMap<>();
                    meta1.put("title", router.get("title"));
                    meta1.put("label", router.get("title"));
                    meta1.put("icon", router.get("icon"));
                    meta1.put("href", router.get("href"));
                    if (Integer.parseInt(router.get("menuType").toString()) == 0) {
                        meta1.put("showAlways", true);
                    }
                    newRouter1.put("meta", meta1);
                    routerOverMap.add(newRouter1);
                }
            }
        }
        for (Map<String, Object> router : routerMap2) {
            Map<String, Object> newRouter = new HashMap<>();
            newRouter.put("id", router.get("id"));
            newRouter.put("parentId", router.get("parentId"));
            newRouter.put("name", router.get("name"));
            newRouter.put("path", router.get("path"));
            newRouter.put("leaf", router.get("menuType"));
            newRouter.put("lvl", router.get("lvl"));
            if (router.get("component") != null && !router.get("component").toString().trim().isEmpty()) {
                newRouter.put("component", router.get("component"));
            }
            Map<String, Object> meta = new HashMap<>();
            meta.put("title", router.get("title"));
            meta.put("label", router.get("title"));
            meta.put("icon", router.get("icon"));
            meta.put("href", router.get("href"));
            if (Integer.parseInt(router.get("menuType").toString()) == 0) {
                meta.put("showAlways", true);
            }
            newRouter.put("meta", meta);
            routerOverMap2.add(newRouter);
            if (!StringUtil.isEmpty(router.get("menuType")) && "1".equals(router.get("menuType").toString()) && !StringUtil.isEmpty(router.get("lvl")) && Integer.parseInt(router.get("lvl").toString()) > 2) {
                List<Map<String, Object>> mapList0 = loginMapper.selMenuData(router.get("parentId").toString());
                String parentId = "";
                if (mapList0.size() > 0 && Integer.parseInt(mapList0.get(0).get("lvl").toString()) > 2) {
                    parentId = getParentPath(mapList0.get(0).get("id").toString());
                } else if (mapList0.size() > 0 && Integer.parseInt(mapList0.get(0).get("lvl").toString()) == 2) {
                    parentId = mapList0.get(0).get("id").toString();
                }
                List<Map<String, Object>> mapList = loginMapper.selMenuParent(parentId);
                if (mapList.size() > 0) {
                    newRouter.put("redirect", mapList.get(0).get("parentPath").toString() + "/" + router.get("path"));
                    Map<String, Object> newRouter1 = new HashMap<>();
                    newRouter1.put("id", router.get("id"));
                    newRouter1.put("parentId", mapList.get(0).get("parentId").toString());
                    newRouter1.put("name", router.get("name"));
                    newRouter1.put("path", router.get("path"));
                    newRouter1.put("leaf", router.get("menuType"));
                    newRouter1.put("lvl", 2);
                    newRouter1.put("hidden", true);
                    if (router.get("component") != null && !router.get("component").toString().trim().isEmpty()) {
                        newRouter1.put("component", router.get("component"));
                    }
                    Map<String, Object> meta1 = new HashMap<>();
                    meta1.put("title", router.get("title"));
                    meta1.put("label", router.get("title"));
                    meta1.put("icon", router.get("icon"));
                    meta1.put("href", router.get("href"));
                    if (Integer.parseInt(router.get("menuType").toString()) == 0) {
                        meta1.put("showAlways", true);
                    }
                    newRouter1.put("meta", meta1);
                    routerOverMap2.add(newRouter1);
                }
            }
        }
        menuMap.put("pcMenuList", routerOverMap);
        menuMap.put("appMenuList", routerOverMap2);
        return menuMap;
    }

    public String getParentPath(String id) {
        List<Map<String, Object>> mapList0 = loginMapper.selMenuData(id);
        if (mapList0.size() > 0 && Integer.parseInt(mapList0.get(0).get("lvl").toString()) > 2) {
            return getParentPath(mapList0.get(0).get("id").toString());
        } else if (mapList0.size() > 0 && Integer.parseInt(mapList0.get(0).get("lvl").toString()) == 2) {
            return mapList0.get(0).get("id").toString();
        }
        return id;
    }

    /**
     * 获取职位对应菜单
     * @param paramMap
     * @param request
     * @return 菜单路由数据
     */
    public Map<String, Object> getPositionRouter(Map<String, Object> paramMap, HttpServletRequest request) {
        Map<String, Object> menuList = new HashMap<>();
        List<Map<String, Object>> routerOverMap = new ArrayList<>();
        List<Map<String, Object>> routerOverMap2 = new ArrayList<>();
        List<Map<String, Object>> routerMap = new ArrayList<>();
        List<Map<String, Object>> routerMap2 = new ArrayList<>();
        String token = request.getHeader(jwtTokenConfig.getHeader());
        Claims claims = jwtTokenConfig.getClaimByToken(token);
        String userId = (String)claims.get(jwtTokenConfig.getSub());
        UserInfo userInfo = (UserInfo)redisTemplate.opsForValue().get(token);
        paramMap.put("userId", userId);
        List<Map<String, Object>> list = loginMapper.selPositionRole(paramMap);
        boolean flag = false;
        if (list != null && list.size() > 0) {
            for (int i = 0; i < list.size(); i++) {
                if (!StringUtil.isEmpty(list.get(0).get("roleName")) && Constant.ROLE_ADMIN.equals(list.get(0).get("roleName").toString())) {
                    flag = true;
                    break;
                } else {
                    flag = false;
                }
            }
        }
        if (userInfo != null && flag) {
            paramMap.put("roleId", list.get(0).get("roleId").toString());
            paramMap.put("appId", "1");
            routerMap = loginMapper.getPosAdminRole(paramMap);
            paramMap.put("appId", "2");
            routerMap2 = loginMapper.getPosAdminRole(paramMap);
        } else {
            paramMap.put("appId", "1");
            routerMap = loginMapper.selPositionRouter(paramMap);
            paramMap.put("appId", "2");
            routerMap2 = loginMapper.selPositionRouter(paramMap);
        }
        for (Map<String, Object> router : routerMap) {
            Map<String, Object> newRouter = new HashMap<>();
            newRouter.put("id", router.get("id"));
            newRouter.put("parentId", router.get("parentId"));
            newRouter.put("name", router.get("name"));
            newRouter.put("path", router.get("path"));
            newRouter.put("leaf", router.get("menuType"));
            newRouter.put("lvl", router.get("lvl"));
            if (router.get("component") != null && !router.get("component").toString().trim().isEmpty()) {
                newRouter.put("component", router.get("component"));
            }
            Map<String, Object> meta = new HashMap<>();
            meta.put("title", router.get("title"));
            meta.put("label", router.get("title"));
            meta.put("icon", router.get("icon"));
            meta.put("href", router.get("href"));
            if (Integer.parseInt(router.get("menuType").toString()) == 0) {
                meta.put("showAlways", true);
            }
            newRouter.put("meta", meta);
            routerOverMap.add(newRouter);
            if (!StringUtil.isEmpty(router.get("menuType")) && "1".equals(router.get("menuType").toString()) && !StringUtil.isEmpty(router.get("lvl")) && Integer.parseInt(router.get("lvl").toString()) > 2) {
                List<Map<String, Object>> mapList0 = loginMapper.selMenuData(router.get("parentId").toString());
                String parentId = "";
                if (mapList0.size() > 0 && Integer.parseInt(mapList0.get(0).get("lvl").toString()) > 2) {
                    parentId = getParentPath(mapList0.get(0).get("id").toString());
                } else if (mapList0.size() > 0 && Integer.parseInt(mapList0.get(0).get("lvl").toString()) == 2) {
                    parentId = mapList0.get(0).get("id").toString();
                }
                List<Map<String, Object>> mapList = loginMapper.selMenuParent(parentId);
                if (mapList.size() > 0) {
                    newRouter.put("redirect", mapList.get(0).get("parentPath").toString() + "/" + router.get("path"));
                    Map<String, Object> newRouter1 = new HashMap<>();
                    newRouter1.put("id", router.get("id"));
                    newRouter1.put("parentId", mapList.get(0).get("parentId").toString());
                    newRouter1.put("name", router.get("name"));
                    newRouter1.put("path", router.get("path"));
                    newRouter1.put("leaf", router.get("menuType"));
                    newRouter1.put("lvl", 2);
                    newRouter1.put("hidden", true);
                    if (router.get("component") != null && !router.get("component").toString().trim().isEmpty()) {
                        newRouter1.put("component", router.get("component"));
                    }
                    Map<String, Object> meta1 = new HashMap<>();
                    meta1.put("title", router.get("title"));
                    meta1.put("label", router.get("title"));
                    meta1.put("icon", router.get("icon"));
                    meta1.put("href", router.get("href"));
                    if (Integer.parseInt(router.get("menuType").toString()) == 0) {
                        meta1.put("showAlways", true);
                    }
                    newRouter1.put("meta", meta1);
                    routerOverMap.add(newRouter1);
                }
            }
        }
        for (Map<String, Object> router : routerMap2) {
            Map<String, Object> newRouter = new HashMap<>();
            newRouter.put("id", router.get("id"));
            newRouter.put("parentId", router.get("parentId"));
            newRouter.put("name", router.get("name"));
            newRouter.put("path", router.get("path"));
            newRouter.put("leaf", router.get("menuType"));
            newRouter.put("lvl", router.get("lvl"));
            if (router.get("component") != null && !router.get("component").toString().trim().isEmpty()) {
                newRouter.put("component", router.get("component"));
            }
            Map<String, Object> meta = new HashMap<>();
            meta.put("title", router.get("title"));
            meta.put("label", router.get("title"));
            meta.put("icon", router.get("icon"));
            meta.put("href", router.get("href"));
            if (Integer.parseInt(router.get("menuType").toString()) == 0) {
                meta.put("showAlways", true);
            }
            newRouter.put("meta", meta);
            routerOverMap2.add(newRouter);
            if (!StringUtil.isEmpty(router.get("menuType")) && "1".equals(router.get("menuType").toString()) && !StringUtil.isEmpty(router.get("lvl")) && Integer.parseInt(router.get("lvl").toString()) > 2) {
                List<Map<String, Object>> mapList0 = loginMapper.selMenuData(router.get("parentId").toString());
                String parentId = "";
                if (mapList0.size() > 0 && Integer.parseInt(mapList0.get(0).get("lvl").toString()) > 2) {
                    parentId = getParentPath(mapList0.get(0).get("id").toString());
                } else if (mapList0.size() > 0 && Integer.parseInt(mapList0.get(0).get("lvl").toString()) == 2) {
                    parentId = mapList0.get(0).get("id").toString();
                }
                List<Map<String, Object>> mapList = loginMapper.selMenuParent(parentId);
                if (mapList.size() > 0) {
                    newRouter.put("redirect", mapList.get(0).get("parentPath").toString() + "/" + router.get("path"));
                    Map<String, Object> newRouter1 = new HashMap<>();
                    newRouter1.put("id", router.get("id"));
                    newRouter1.put("parentId", mapList.get(0).get("parentId").toString());
                    newRouter1.put("name", router.get("name"));
                    newRouter1.put("path", router.get("path"));
                    newRouter1.put("leaf", router.get("menuType"));
                    newRouter1.put("lvl", 2);
                    newRouter1.put("hidden", true);
                    if (router.get("component") != null && !router.get("component").toString().trim().isEmpty()) {
                        newRouter1.put("component", router.get("component"));
                    }
                    Map<String, Object> meta1 = new HashMap<>();
                    meta1.put("title", router.get("title"));
                    meta1.put("label", router.get("title"));
                    meta1.put("icon", router.get("icon"));
                    meta1.put("href", router.get("href"));
                    if (Integer.parseInt(router.get("menuType").toString()) == 0) {
                        meta1.put("showAlways", true);
                    }
                    newRouter1.put("meta", meta1);
                    routerOverMap2.add(newRouter1);
                }
            }
        }
        List<PriviInterCustom> menus = userCustomMapper.selAdminRoleMenuByUserPosId(paramMap);
        userInfo.setPositionMenus(menus);
        userInfo.setMenuFlag("0");
        //redisTemplate.opsForValue().set(token + "positionMenus", menus, 24L, TimeUnit.HOURS);
        //redisTemplate.opsForValue().set(token + "menuFlag", "0", 24L, TimeUnit.HOURS);
        List<Map<String, Object>> listMap = loginMapper.selUserPositionData(paramMap);
        String orgId = "";
        String corpId = "";
        String levelId = "";
        String corpName = "";
        String structName = "";
        String deptId = "";
        String structId = "";
        String lineId = "";
        String postId = "";
        String dataRghtFlag = "";
        if (listMap != null && listMap.size() > 0) {
            if (!StringUtil.isEmpty(listMap.get(0).get("orgId"))) {
                orgId = listMap.get(0).get("orgId").toString();
            }
            if (!StringUtil.isEmpty(listMap.get(0).get("corpId"))) {
                corpId = listMap.get(0).get("corpId").toString();
            }
            if (!StringUtil.isEmpty(listMap.get(0).get("levelId"))) {
                levelId = listMap.get(0).get("levelId").toString();
            }
            if (!StringUtil.isEmpty(listMap.get(0).get("structName"))) {
                structName = listMap.get(0).get("structName").toString();
            }
            if (!StringUtil.isEmpty(listMap.get(0).get("corpName"))) {
                corpName = listMap.get(0).get("corpName").toString();
            }
            if (!StringUtil.isEmpty(listMap.get(0).get("deptId"))) {
                deptId = listMap.get(0).get("deptId").toString();
            }
            if (!StringUtil.isEmpty(listMap.get(0).get("structId"))) {
                structId = listMap.get(0).get("structId").toString();
            }
            if (!StringUtil.isEmpty(listMap.get(0).get("lineId"))) {
                lineId = listMap.get(0).get("lineId").toString();
            }
            if (!StringUtil.isEmpty(listMap.get(0).get("postId"))) {
                postId = listMap.get(0).get("postId").toString();
            }
            if (!StringUtil.isEmpty(listMap.get(0).get("structType"))) {
                if ("1".equals(listMap.get(0).get("structType").toString()) || "3".equals(listMap.get(0).get("structType").toString())) {
                    userInfo.setOrgName(structName);
                    userInfo.setDeptName(null);
                } else if ("2".equals(listMap.get(0).get("structType").toString())) {
                    userInfo.setDeptName(structName);
                    userInfo.setOrgName(null);
                }
            }
            if (!StringUtil.isEmpty(listMap.get(0).get("dataRghtFlag"))) {
                dataRghtFlag = listMap.get(0).get("dataRghtFlag").toString();
            }
        }
        userInfo.setOrgId(orgId);
        userInfo.setCorpId(corpId);
        userInfo.setCorpName(corpName);
        userInfo.setOrgRank(levelId);
        userInfo.setDeptId(deptId);
        userInfo.setStructId(structId);
        userInfo.setLineId(lineId);
        userInfo.setPostId(postId);
        userInfo.setDataRghtFlag(dataRghtFlag);
        Map<String,Object> map0 = new HashMap<>();
        map0.put("userId", userInfo.getUserId());
        map0.put("positionId", userInfo.getPositionId());
        map0.put("roleName", Constant.ROLE_ADMIN);
        List<Map<String,Object>> adminRoleList = commonMapper.queryAdminRole(map0);
        userInfo.setAdminRoleList(adminRoleList);
        userInfo.setAdminRoleFlag("1");
        //修改用户缓存数据
        if (!StringUtil.isEmpty(paramMap.get("positionId"))) {
            userInfo.setPositionId(paramMap.get("positionId").toString());
            if (redisTemplate.hasKey(token)) {
                redisTemplate.delete(token);
            }
            redisTemplate.opsForValue().set(token, userInfo, 24L, TimeUnit.HOURS);
        }
        menuList.put("pcMenuList", routerOverMap);
        menuList.put("appMenuList", routerOverMap2);
        //redisTemplate.opsForValue().set(token + "adminRoleList", adminRoleList, 24L, TimeUnit.HOURS);
        return menuList;
    }

    /**
     * 获取法人信息
     * @param map
     * @return 用户所属法人集合
     */
    public List<Map<String, Object>> selCorpId(Map<String, Object> map) {
        return loginMapper.selCorpId(map);
    }

    /**
     * 修改密码
     * @param map
     */
    @Transactional
    public void updatePassword(Map<String, Object> map, HttpServletRequest request) {
        Base64 base64 = new Base64();
        if (!StringUtil.isEmpty(map.get("password"))) {
            map.put("password", base64.getBase64Encode(map.get("password").toString()));
        }
        String token = request.getHeader(jwtTokenConfig.getHeader());
        Claims claims = jwtTokenConfig.getClaimByToken(token);
        String userId = (String)claims.get(jwtTokenConfig.getSub());
        map.put("userId", userId);
        loginMapper.updatePassword(map);
        List<Map<String, Object>> list = userCustomMapper.selPolicy(map.get("userId").toString());
        list.removeAll(Collections.singleton(null));
        if (list != null && list.size() > 0) {
            PriviUser priviUser = new PriviUser();
            priviUser.setPasswdErrorTimes(new BigDecimal(Integer.parseInt(list.get(0).get("maxRetryTimes").toString())));
            priviUser.setPasswdExpiredTime(DateTimeUtil.getAddTime(Integer.parseInt(list.get(0).get("activeDays").toString())));
            PriviUserExample priviUserExample = new PriviUserExample();
            PriviUserExample.Criteria criteria = priviUserExample.createCriteria();
            criteria.andUserIdEqualTo(map.get("userId").toString());
            userMapper.updateByExampleSelective(priviUser, priviUserExample);
        }
    }

    /**
     * 获取密码规则
     * @param map
     * @return 用户所属法人密码规则
     */
    public Map<String, Object> selPassRule(Map<String, Object> map) {
        List<Map<String, Object>> list = loginMapper.selCorpPassRule(map);
        if (list != null && list.size() > 0) {
            return list.get(0);
        }
        return null;
    }

    /**
     * 主职位对应法人信息
     * @param map
     * @return
     */
    public List<Map<String, Object>> selMainCorpId(Map<String, Object> map) {
        return loginMapper.selMainCorpId(map);
    }

    /**
     * 获取所有法人
     * @return
     */
    public List<Map<String, Object>> selSysCorp() {
        return loginMapper.selSysCorp();
    }

    /**
     * 锁定用户
     * @param map
     */
    public void lockUser(Map<String, Object> map) {
        map.put("userSts", Constant.USER_STATE_TWO);
        loginMapper.lockUser(map);
    }

    /**
     * 查询菜单对应接口
     * @param map
     * @return
     */
    public List<Map<String, Object>> selInterface(Map<String, Object> map) {
        return loginMapper.selInterface(map);
    }

    /**
     * 退出登录 注销redis
     * @param request
     */
    public void logout (HttpServletRequest request) {
        try {
            String token = request.getHeader(jwtTokenConfig.getHeader());
            Claims claims = jwtTokenConfig.getClaimByToken(token);
            String userId = (String)claims.get(jwtTokenConfig.getSub());
            if (StringUtil.isEmpty(userId)) {
                throw new AppAuthException(ErrorCode.ErrorCodeEnum.ACCESS_USER_INFO);
            } else {
                if (redisTemplate.hasKey(token)) {
                    redisTemplate.delete(token);
                }
            }
        } catch (AppAuthException e) {
            log.error(e.getMessage());
        }
    }

}
